package com.wcgksoft.dao;

import org.hibernate.*;
import org.hibernate.criterion.CriteriaSpecification;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Projections;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;

import java.io.Serializable;
import java.util.List;


public class EntityDaoImpl<T> extends HibernateDaoSupport implements EntityDao<T> {

  public long totalCount;


  private Class<T> clazz;

  // 按照类型自动注入SessionFactory; 在实例化的时候,Spring按照形参的类型自动注入这招好哈哈哈 ---

  /**
   * 注入SessionFactory
   *
   * @author 阿良
   */
  @Autowired
  public void setMySessionFactory(SessionFactory sessionFactory) {
    setSessionFactory(sessionFactory);
  }

/*    public EntityDaoImpl() {
        //this表示当前被实例化的对象；如UserDaoImpl
        ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass();//BaseDaoImpl<User>
        clazz = (Class<T>) pt.getActualTypeArguments()[0];
    }*/

  /**
   * 获取session
   *
   * @return session
   */
  public Session getCurrentSession() {
    Session session = null;
    try {
      session = getSessionFactory().getCurrentSession();
    } catch (HibernateException e) {
      throw new RuntimeException("getCurrentSession error", e);
      //session = getSessionFactory().openSession();
    }
    return session;
  }


  /**
   * 增
   */
  public void saveOrUpdate(T entity) {
    getCurrentSession().saveOrUpdate(entity);
  }


  /**
   * 合并session增
   */
  public <T> T saveMerge(T entity) {
    return this.getHibernateTemplate().merge(entity);
  }

  /**
   * 增
   */
  public void save(T entity) {
    this.getHibernateTemplate().save(entity);
  }

  /**
   * 改
   */
  public void update(T entity) {
    this.getHibernateTemplate().update(entity);
  }

  /**
   * 删
   */
  public void delete(T entity) {
    this.getHibernateTemplate().delete(entity);
  }

  /**
   * 查
   */
  public T findById(Class beanClass, Serializable id) {
    return (T) this.getHibernateTemplate().get(beanClass, id);
  }

  @SuppressWarnings({"unchecked", "rawtypes"})
  public List<T> findAll(Class beanClass) {
    String hql = "FROM " + beanClass.getSimpleName();
    return (List<T>) this.getHibernateTemplate().find(hql);
  }

  /**
   * 离线条件查询
   */
  @SuppressWarnings({"unchecked", "rawtypes"})
  public List<T> findByConditions(DetachedCriteria criteria, int startIndex, int pageSize) {
    Criteria criterias = criteria.getExecutableCriteria(this.getSessionFactory().getCurrentSession());
    Long totalNum = (Long) criterias.setProjection(Projections.rowCount()).uniqueResult();
    this.setTotalCount(totalNum);
    criterias.setProjection(null);
    criteria.setResultTransformer(CriteriaSpecification.ROOT_ENTITY);//设置查询结果为实体对象，
    List list = this.getHibernateTemplate().findByCriteria(criteria, (startIndex - 1) * pageSize, pageSize);
    return list;
  }

  /**
   * 离线条件查询
   */
  @SuppressWarnings({"unchecked", "rawtypes"})
  public List<T> findByConditions(DetachedCriteria criteria) {
    List list = this.getHibernateTemplate().findByCriteria(criteria);
    return list;
  }

  @SuppressWarnings({"unchecked", "rawtypes"})
  public List<T> findByNamedQuery(String queryName, Object... objs) {
    return (List<T>) this.getHibernateTemplate().findByNamedQuery(queryName, objs);
  }

  public void executeNamedQuery(String queryName, Object... objs) {
    Session session = this.getSessionFactory().openSession();
    Query query = session.getNamedQuery(queryName);
    if (objs != null && objs.length > 0) {
      int i = 0;
      for (Object object : objs) {
        query.setParameter(i++, object);
      }
    }
    query.executeUpdate();
  }

  /**
   * 执行HQL语句
   *
   * @param hql
   */
  public void createHQLQuery(String hql) {
    Session session = this.getSessionFactory().openSession();
    Query query = session.createQuery(hql);
    query.executeUpdate();
  }

  /*hibernate执行hql*/
/*    public List<> createHQLQueryClass(Query query) {
        Session session = this.getSessionFactory().openSession();
        Query querys=session.createQuery(hql);
        return querys.list();
    }*/

  public long getTotalCount() {
    return totalCount;
  }

  public void setTotalCount(long totalCount) {
    this.totalCount = totalCount;
  }


}
